import { visit } from "recast";
import config from "../../boompack.config.js";

/**
 * 判断是否为对象的Key值或属性变量，且是obj.a这种模式，不是obj[a]这种模式
 * @returns
 */
const isNoComputeProperty = (path) => {
  return (
    path.name === "key" ||
    (path.name === "property" && path.parent.node.computed === false)
  );
};

/**
 * 判断变量名是否需要被替换
 * @param {变量名} name
 */
const replaceCondition = (name) => {
  return name.length === 1 && !config.ignoreVarName.includes(name);
};

/**
 * 替换单字符变量的名字为长名
 * 方便后续批量编辑
 * @param {抽象语法树} ast
 */
const replaceVarName = (ast) => {
  const dict = {};
  // 访问所有的变量声明获取变量名映射字典
  visit(ast, {
    visitVariableDeclarator: function (path) {
      if (replaceCondition(path.node.id.name)) {
        if (!dict[path.node.id.name]) {
          dict[path.node.id.name] = `var_${path.node.id.name}`;
        }
      }
      this.traverse(path);
    },
  });

  // 访问所有的函数声明，加入变量名映射字典
  visit(ast, {
    visitFunctionDeclaration: function (path) {
      if (replaceCondition(path.node.id.name)) {
        if (!dict[path.node.id.name]) {
          dict[path.node.id.name] = `func_${path.node.id.name}`;
        }
      }
      this.traverse(path);
    },
  });

  // 替换变量名字
  visit(ast, {
    visitIdentifier: function (path) {
      if (!isNoComputeProperty(path) && replaceCondition(path.node.name)) {
        if (dict[path.node.name]) {
          path.node.name = dict[path.node.name];
        }
      }
      this.traverse(path);
    },
  });
};

export default replaceVarName;
